#pragma once
#include <string>

struct case_insensitive_traits : std::char_traits<char>
{
	static bool eq(char a, char b) {
		return tolower(a) == tolower(b);
	}
	static bool ne(char a, char b) {
		return !eq(a, b);
	}
	static bool lt(char a, char b) {
		return tolower(a) < tolower(b);
	}
	static bool gt(char  a, char  b) {
		return tolower(a) > tolower(b);
	}
	static int compare(const char* a, const char* b, size_t n) {
		for (size_t i = 0; i < n; ++i) {
			int delta = tolower(a[i]) - tolower(b[i]);
			if (delta != 0) {
				return delta;
			}
		}
		return 0;
	}
	static const char* find(const char* s, size_t n, char c) {
		c = tolower(c);
		for (size_t i = 0; i < n; ++i, ++s) {
			if (tolower(*s) == c) {
				return s;
			}
		}
		return nullptr;
	}
};

struct case_insensitive_wstring_traits : std::char_traits<wchar_t>
{
	static bool eq(wchar_t a, wchar_t b) {
		return tolower(a) == tolower(b);
	}
	static bool ne(wchar_t a, wchar_t b) {
		return !eq(a, b);
	}
	static bool lt(wchar_t a, wchar_t b) {
		return tolower(a) < tolower(b);
	}
	static bool gt(wchar_t  a, wchar_t  b) {
		return tolower(a) > tolower(b);
	}
	static int compare(const wchar_t* a, const wchar_t* b, size_t n) {
		for (size_t i = 0; i < n; ++i) {
			int delta = tolower(a[i]) - tolower(b[i]);
			if (delta != 0) {
				return delta;
			}
		}
		return 0;
	}
	static const wchar_t* find(const wchar_t* s, size_t n, wchar_t c) {
		c = tolower(c);
		for (size_t i = 0; i < n; ++i, ++s) {
			if (tolower(*s) == c) {
				return s;
			}
		}
		return nullptr;
	}
};
